class Replacer {
  constructor(mapping) {
    this.mapping = new Map(Object.entries(mapping));
  }
  replace(source = {}) {
    if (!this.mapping) {
      return source;
    }

    for (let [targetKey, sourceKey] of this.mapping) {
      if (typeof sourceKey === "function") {
        source[targetKey] = sourceKey(source);
      } else {
        source[targetKey] = source[sourceKey];
      }
    }

    return source;
  }
}

class Transformer {
  constructor(baseURL, url, method) {
    this.baseURL = baseURL;
    this.url = url;
    this.method = method.toUpperCase();
  }
  getTransformerKey() {
    return this.method.toUpperCase() + " " + this.baseURL + this.url;
  }
  getBackTransformerKey() {
    return (
      (this.targetMethod || this.method).toUpperCase() +
      " " +
      (this.targetBaseURL || this.baseURL) +
      (this.targetUrl || this.url)
    );
  }
  setTargetUrl(targetUrl) {
    this.targetUrl = targetUrl;
  }
  setTargetMethod(targetMethod) {
    this.targetMethod = targetMethod;
  }
  setTargetBaseURL(baseURL) {
    this.targetBaseURL = baseURL;
  }
  configure({ params, data, headers, response }) {
    if (params) {
      if (params instanceof Resolver) {
        this.paramResolver = params;
      } else {
        this.paramReplacer = new Replacer(params);
      }
    }
    if (headers) {
      if (headers instanceof Resolver) {
        this.headerResolver = headers;
      } else {
        this.headerReplacer = new Replacer(headers);
      }
    }
    if (data) {
      if (data instanceof Resolver) {
        this.dataResolver = headers;
      } else {
        this.dataReplacer = new Replacer(data);
      }
    }
    if (response) {
      if (response instanceof Resolver) {
        this.responseResolver = response;
      } else {
        this.responseReplacer = new Replacer(response);
      }
    }
  }
}

function throwIfMissing() {
  throw new Error("Resolver必须实现转换逻辑!!!");
}

class Resolver {
  constructor(resolver = throwIfMissing()) {
    this.resolver = resolver;
  }
  // 实现该方法
  resolve(any) {
    return this.resolver(any);
  }
}

class Transformers {
  constructor() {
    this.transformers = {};
    this.backTransformers = {};
  }
  transformerKey(config) {
    let url = config.method.toUpperCase() + " " + config.baseURL + config.url;
    if (config.url.startsWith("http://") || config.url.startsWith("https://")) {
      url = config.method.toUpperCase() + " " + config.url;
    }
    let index = url.indexOf("?");
    if (index > 0) {
      return url.substring(0, index);
    }
    return url;
  }
  transferRequest(config) {
    let key = this.transformerKey(config);
    let transformer = this.transformers[key];
    if (!transformer) {
      return config;
    }

    if (transformer.targetMethod) {
      config.method = transformer.targetMethod;
    }

    if (transformer.targetBaseURL) {
      config.baseURL = transformer.targetBaseURL;
    }

    if (transformer.targetUrl) {
      config.url = transformer.targetUrl;
    }

    if (transformer.paramReplacer) {
      config.params = transformer.paramReplacer.replace(config.params);
    }

    if (transformer.paramResolver) {
      config.params = transformer.paramResolver.resolve(config);
    }

    if (transformer.dataReplacer) {
      config.data = transformer.dataReplacer.replace(config.data);
    }

    if (transformer.dataResolver) {
      config.data = transformer.dataResolver.resolve(config);
    }

    if (transformer.headerReplacer) {
      config.headers = transformer.headerReplacer.replace(config.headers);
    }

    if (transformer.headerResolver) {
      config.headers = transformer.headerResolver.resolve(config);
    }

    return config;
  }
  transferResponse(response) {
    let key = this.transformerKey(response.config);
    let transformer = this.backTransformers[key];
    if (!transformer) {
      return response;
    }

    if (transformer.responseReplacer) {
      response.data = transformer.responseReplacer.replace(response.data);
    }

    if (transformer.responseResolver) {
      response.data = transformer.responseResolver.resolve(response);
    }

    return response;
  }
  register(transformer) {
    let transformerKey = transformer.getTransformerKey();
    this.transformers[transformerKey] = transformer;

    let backTransformerKey = transformer.getBackTransformerKey();
    this.backTransformers[backTransformerKey] = transformer;
  }
}

let transformers = new Transformers();

export default transformers;
export { Transformer, Resolver };

/**
// 使用方法
let transfomer = new Transformer("http://192.168.1.89:1256", "/customer/customer/search", "post")
transfomer.setTargetMethod('put')
transfomer.setTargetUrl('/customer/customer/searchNew')
transfomer.configure({params: {a: (params)=> 'x' + params['x']}, data: {x: ()=> 'xxxx'}, headers: {'xxx': ()=> 'x'},  resolver: new Resolver()})
transformers.register(transfomer)

// 使用Resolver
let transfomer2 = new Transformer("http://192.168.1.89:1256", "/customer/customer", "post")
transfomer2.setTargetUrl('/customer/customer/new')
transfomer2.configure({params: new CustomerParamResolver(), data: {x: ()=> 'xxxx'}, headers: {'xxx': ()=> 'x'},  resolver: new Resolver()})
transformers.register(transfomer2)
 */
